package prefix.loan.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.ArrayUtils;

import models.LoanApp.LoanType;


public enum LoanMaturity {
	//add some new months, added by jason
	Month1 (1,"1 Month Fixed", false),//
	Month3 (3,"3 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month4 (4,"4 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month5 (5,"5 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month6 (6,"6 Months Fixed", true,LoanType.PERSONAL,LoanType.BUSINESS),//
	Month7 (7,"7 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month8 (8,"8 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month9 (9,"9 Months Fixed", true,LoanType.PERSONAL,LoanType.BUSINESS),//
	Month10 (10,"10 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month11 (11,"11 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Year1 (12,"1 Year Fixed", true,LoanType.PERSONAL,LoanType.BUSINESS),//
	Month13 (13,"13 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month14 (14,"14 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month15 (15,"15 Months Fixed", true,LoanType.PERSONAL,LoanType.BUSINESS),//
	Month16 (16,"16 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month17 (17,"17 Months Fixed", true, LoanType.PERSONAL,LoanType.BUSINESS),//
	Month18 (18,"18 Months Fixed", true,LoanType.PERSONAL,LoanType.BUSINESS),//
	Year2 (24,"2 Years Fixed", false),//
	Year3 (36,"3 Year Fixed", false),//
	Year5 (60,"5 Year Fixed", false),//
	;
	
	// number of months represented by this maturity
	public int NUMBER_OF_MONTHS;
	public String PROGRAM_NAME;
	private boolean enabled;
	private LoanType[] enableLoanTypes;
	
	/**
	 * Constructor: requires number of months represented by this loan maturity
	 * @param months
	 */
	private LoanMaturity(int months, String programName, boolean enabled, LoanType... loanTypes) {
		NUMBER_OF_MONTHS = months;
		PROGRAM_NAME = programName;
		this.enabled = enabled;
		this.enableLoanTypes = loanTypes;
	}
	

	public int getMaturity() {
		return NUMBER_OF_MONTHS;
	}
	public String getProgramName() {
		return PROGRAM_NAME;
	}	
	public boolean isEnabled() {
		return enabled;
	}
	public LoanType[] getEnableLoanType(){
	    return this.enableLoanTypes;
	}
	public static LoanMaturity getMaturity(Integer duration) {
		LoanMaturity maturity = null;
		if(duration != null) {
			for(LoanMaturity mat:LoanMaturity.values()) {
				if(mat.getMaturity() == duration) {
					maturity = mat;
				}
			}
		}
		return maturity;
	}

    /**
     * Get Loan maturity by name as string
     * 
     * @param maturity
     * @return
     */
    public static LoanMaturity getMaturity(String maturity) {
	if (maturity != null) {
	    for (LoanMaturity mat : LoanMaturity.values()) {
		if (mat.name().equals(maturity)) {
		    return mat;
		}
	    }
	}
	return null;
    }

    /**
     * Get enabled maturities
     * 
     * @return
     */
    public static List<LoanMaturity> getMaturities() {
	List<LoanMaturity> maturities = new ArrayList<LoanMaturity>();
	for (LoanMaturity maturity : LoanMaturity.values()) {
	    if (maturity.isEnabled()) {
	        maturities.add(maturity);
	    }
	}
	return maturities;
    }

    public static List<LoanMaturity> getMaturities(String loanTypeStr) {
        List<LoanMaturity> maturities = new ArrayList<LoanMaturity>();
        try {
            LoanType loanType = LoanType.valueOf(loanTypeStr);
            for (LoanMaturity maturity : LoanMaturity.values()) {
                if (maturity.isEnabled() && ArrayUtils.contains(maturity.getEnableLoanType(), loanType)) {
                    maturities.add(maturity);
                }
            }

        } catch (Exception e) {
            // do nothing
        }
        return maturities;

    }
    
    /**
     * Returns the minimum maturity for the specified loan type. 
     * If loan type is null, the overall min maturity is returned
     */
	public static LoanMaturity getMinMaturity(LoanType loanType) {
		LoanMaturity min = null;
		
		for (LoanMaturity maturity : LoanMaturity.values()) {
			if (maturity.isEnabled() &&
					(loanType == null || ArrayUtils.contains(maturity.getEnableLoanType(), loanType)) &&
					(min == null || min.getMaturity() > maturity.getMaturity())) {
				min = maturity;
			}
		}
		
		return min;
	}
	
	/**
     * Returns the maximum maturity for the specified loan type. 
     * If loan type is null, the overall max maturity is returned
     */
	public static LoanMaturity getMaxMaturity(LoanType loanType) {
		LoanMaturity max = null;
		
		for (LoanMaturity maturity : LoanMaturity.values()) {
			if (maturity.isEnabled() &&
					(loanType == null || ArrayUtils.contains(maturity.getEnableLoanType(), loanType)) &&
					(max == null || max.getMaturity() < maturity.getMaturity())) {
				max = maturity;
			}
		}
		
		return max;
	}
}